#include "Win32Console.h"


Win32Console* Win32Console::instance = 0;


Win32Console* Win32Console::GetInstance()
{
	if (instance == 0)
		instance = new Win32Console();
	return instance;
}


Win32Console::Win32Console()
	: osf_in(0), osf_out(0), fd_in(0), fd_out(0)
{
	//this->isAllocated = false;

    AllocConsole();
    osf_in = _open_osfhandle( (intptr_t)GetStdHandle(STD_INPUT_HANDLE), _O_TEXT );
    osf_out = _open_osfhandle( (intptr_t)GetStdHandle(STD_OUTPUT_HANDLE), _O_TEXT );
    if( osf_in == -1 || osf_out == -1 ) {
        MessageBoxA( NULL, "failed allocating the console", "crap!", MB_OK|MB_ICONERROR );
        return;
    }
    or_stdin = *stdin;
    or_stdout = *stdout;
    fd_in = _fdopen( osf_in, "r" );
    fd_out = _fdopen( osf_out, "w" );
    if( fd_in == INVALID_HANDLE_VALUE || fd_out == INVALID_HANDLE_VALUE ) {
        MessageBoxA( NULL, "failed opening the console", "crap!", MB_OK|MB_ICONERROR );
        _close( osf_in );
        _close( osf_out );
        osf_in = osf_out = 0;
        fd_in = fd_out = 0;
        return;
    }
    *stdin = *fd_in;
    *stdout = *fd_out;
    std::cin.clear();
    std::cout.clear();
}


Win32Console::~Win32Console()
{
	::FreeConsole();
    if( fd_in )
        *stdin = or_stdin;
    if( fd_out )
        *stdout = or_stdout;
    if( fd_in )
        fclose( fd_in );
    if( fd_out )
        fclose( fd_in );
    if( osf_in )
        _close( osf_in );
    if( osf_out )
        _close( osf_out );
}


//void Win32Console::Allocate()
//{
//	isAllocated = (::AllocConsole() != 0);
//}
//
//
//void Win32Console::Free()
//{
//	::FreeConsole();
//}
//
//
//void __cdecl Win32Console::Write(string format, ...)
//{
//	va_list ap;
//	va_start(ap, format);
//	
//	Write(format, ap);
//	
//	va_end(ap);
//}
//
//
//void __cdecl Win32Console::Write(string format, va_list ap)
//{
//	char buffer[256] = {0};
//	auto n = vsnprintf_s(buffer, sizeof(buffer), format.c_str(), ap);
//
//	auto handle = GetStdHandle(STD_OUTPUT_HANDLE);
//	DWORD dummy = 0;
//
//	if (::WriteConsole(handle, buffer, n, &dummy, NULL) == 0) {
//		throw "WriteConsole() failed";
//	}
//}
//
//
//void __cdecl Win32Console::writeLine(string format, ...)
//{
//	va_list ap;
//	va_start(ap, format);
//	
//	WriteLine(format, ap);
//	
//	va_end(ap);
//}
//
//
//void __cdecl Win32Console::WriteLine(string format, va_list ap)
//{
//	Write(format, ap);
//	Write("\n");
//}
